package com.golf.client.course.renderer;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.util.Formatter;

import com.golf.client.player.InteractivePlayer;
import com.golf.core.course.bodies.Position;
import com.golf.core.course.bodies.Vector;

/**
 * A renderer that is able to show the actions of an interactive
 * player: aiming, shooting, etc. 
 * 
 * @author gfloodgate
 */
public class InteractivePlayerRenderer implements CanvasRenderer
{
	
	/** An ~50% alpha white colour (for indicator bar, and debug text), not immutable, so don't share. */
	private final Color ALPHA_WHITE = new Color(255, 255, 255, 170);
	
	/** A red colour (for indicator bar, and debug text), not immutable, so don't share. */
	private final Color RED = Color.RED;
	
	/** A small font, not immutable, so don't share. */
	private final Font SMALL_FONT = new Font("Arail",Font.PLAIN, 9);
	
	
	/** The interactive player that this renderer is responsible for. */
	private InteractivePlayer player;
	
	
	/**
	 * Create a renderer for an interactive player. This renderer will
	 * ensure that the player can see where he is hitting, how hard, etc.
	 * 
	 * @param player The interactive player that this renderer will look after.
	 */
	public InteractivePlayerRenderer(InteractivePlayer player)
	{
		this.player = player;
	}

	
	/**
	 * {@inheritDoc}
	 */
	public void render(final Graphics g, final Dimension dim)
	{
		if (player.isTurn() && player.isInteracting())
		{
			drawPlayerAim(g, player);
		}
		
		drawDebugInformation(g, player);
	}
	
	

	/**
	 * Draw the current aim and power of this interactive user.
	 * 
	 * @param g The graphics context to draw the debug information onto.
	 * @param player The player to draw aim for.
	 */
	private void drawPlayerAim(final Graphics g, final InteractivePlayer player)
	{
		final Position ballPosition = player.getBall().getPosition();
		
		final Vector vector = player.getAimVector();
		double angle = vector.getAngle();
		double power = vector.getSpeed() - 25;
		
		// Set the rendering color to a translucent white.
		g.setColor(ALPHA_WHITE);
		
		// Draw the power line, and debug onward tail.
		double dx = ballPosition.getX() + (power * Math.sin(angle));
		double dy = ballPosition.getY() - (power * Math.cos(angle));
		g.drawLine((int)ballPosition.getX(), (int)ballPosition.getY(), (int)dx, (int)dy); 

		dx = ballPosition.getX() - (10 * Math.sin(angle));
		dy = ballPosition.getY() + (10 * Math.cos(angle));
		g.drawLine((int)ballPosition.getX(), (int)ballPosition.getY(), (int)dx, (int)dy); 
	}	



	/**
	 * Draw debug information and axes.
	 * 
	 * @param g The graphics context to draw the debug information onto.
	 * @param player The player to draw debug information for.
	 */
	private void drawDebugInformation(final Graphics g, final InteractivePlayer player)
	{
		// Set the rendering color to red.
		g.setColor(RED);
		
		final Position ballPosition = player.getBall().getPosition();
		final int bx = (int)ballPosition.getX();
		final int by = (int)ballPosition.getY();
		
		// Draw the vertical (Y) debug axis.
		g.drawLine(bx, by, bx, by - 30);
		g.drawLine(bx, by - 30, bx - 3, by - 27);
		g.drawLine(bx - 3, by - 27, bx + 3, by - 27);
		g.drawLine(bx + 3, by - 27, bx, by - 30);

		// Draw the horizontal (X) debug axis.
		g.drawLine(bx, by, bx + 30, by);
		g.drawLine(bx + 30, by, bx + 27, by - 3);
		g.drawLine(bx + 27, by - 3, bx + 27, by + 3);
		g.drawLine(bx + 27, by + 3, bx + 30, by);
		
		// Set the rendering color to a translucent white.
		g.setColor(ALPHA_WHITE);

		final StringBuilder buffer = new StringBuilder();
		if (player.isInteracting())
		{
			// The player is interacting, show aim and power.
			Vector vector = player.getAimVector();
			double angle = vector.getAngle();
			double power = vector.getSpeed() - 25;
			
			final Formatter f = new Formatter(buffer);
			f.format("%3.0f\u00B0 (%3.0f)", 180 + Math.toDegrees(angle), power);
		}
		else
		{
			// If the plater is not interacting, indicate so.
			buffer.append("-- (--)");
		}

		// Draw the debug text.
		g.setFont(SMALL_FONT);
		g.drawString(buffer.toString(), bx + 10, by - 10);	
	}
	
}
